Skip to content

feat: rewrite rounding as a string-digit algorithm; support all RoundingMode modes and bcdivmod (closes #36, #39)#82

Merged
nanasess merged 5 commits into
mainfrom
worktree-feat+symfony-compat-rounding
Jul 3, 2026
Merged

feat: rewrite rounding as a string-digit algorithm; support all RoundingMode modes and bcdivmod (closes #36, #39)#82
nanasess merged 5 commits into
mainfrom
worktree-feat+symfony-compat-rounding

Conversation

@nanasess

@nanasess nanasess commented Jul 3, 2026

Copy link
Copy Markdown
Owner

Overview

Following the source-level comparison with symfony/polyfill-php84 (#81), this PR rewrites the rounding path from a phpseclib BigInteger-based implementation to pure string-digit arithmetic and fills the remaining feature gaps. It combines the previously-planned PRs A/B/C into one, using a clean re-implementation (no code copied).

Why rewrite the rounding

The previous bcround() fell back to round((float) ...) for HalfEven/HalfOdd, abandoning arbitrary precision and returning wrong results for large or high-precision inputs (see #81):

bcround('12345678901234567890.5', 0, RoundingMode::HalfEven)
  old pkg : 12345678901234567168   <- float corrupts the low-order digits
  native  : 12345678901234567890
  new     : 12345678901234567890   OK

symfony processes every mode with pure string arithmetic (its rounding does not call the native bc extension), so adopting that approach improves correctness and performance at the same time.

Changes

File Change
lib/RoundingMode.php backed string enum → pure enum
lib/bcmath.php $operand$num; add bcdivmod wrapper
src/BCMath.php rewrite the rounding core as string-digit arithmetic (all 8 modes + negative precision); rework convertRoundingMode; route floor/ceil through the core; add divmod()
tests/BCMathTest.php replace the "directional modes throw" expectations with correct-result assertions; add high-precision regression and bcdivmod tests
.github/workflows/ci.yml remove 8 now-passing phpt tests from --skip
phpstan.neon.dist adjust ignores for the pure-enum change; ignore a pre-existing (main) PHP 8.1-only in_array false positive
README.md document new functions; add a three-way comparison with symfony/polyfill-php84; note the coexistence behavior

The rounding algorithm is a clean re-implementation inspired by symfony/polyfill-php84 (MIT); no code was copied. The relevant method carries an attribution comment.

Verification (local, PHP 8.5.4 with the bcmath extension)

  • PHPUnit: 279 tests, 1310 assertions, OK (added directional / high-precision / bcdivmod tests)

  • PHPStan (level max): No errors

  • php-cs-fixer: 0 findings

  • Native parity: bcround checked over 8 modes × 21 inputs (including high precision and negative precision) → 0 mismatches; bcdivmod matches too, and division by zero throws DivisionByZeroError('Division by zero')

  • Performance (N=20000, ms): dropping the BigInteger dependency speeds up the rounding functions

    Operation old pkg new pkg native
    bcround(HalfAway) 156.5 31.6 1.9
    bcround 30-digit high precision 184.6 31.4 1.5
    bcceil 128.5 28.5 1.3

PHPT skips resolved (no-extension environment)

The following 8 official phpt tests, previously skipped in docker-phpt-tests, now pass and were removed from --skip:
bcdivmod, bcdivmod_by_zero, bcround_all, bcround_away_from_zero, bcround_ceiling, bcround_floor, bcround_toward_zero, bcround_early_return

(The remaining scale_ini / gh20006 / bcround_precision_bounds skips depend on the INI setting or the BcMath\Number OOP API and are out of scope.)

Compatibility / impact

  • All previously-passing tests still pass (HalfAway/HalfTowards behavior, negative-zero normalization, trailing-zero padding, the precision-bound ValueError, and the version-dependent is_numeric behavior are preserved).
  • Default-mode (HalfAwayFromZero) and single-argument floor/ceil results are unchanged (no impact on EC-CUBE's usage pattern; verified in Compatibility differences with symfony/polyfill-php84 when both are installed #81).

Note on the PHPStan job

The PHPStan job was already failing on main with a single PHP 8.1-only false positive (in_array() reported as always-true at tests/BCMathTest.php). It is unrelated to this PR; it is silenced here so the job can go green.

Refs #81
Closes #36
Closes #39

🤖 Generated with Claude Code

nanasess and others added 3 commits July 3, 2026 17:23
symfony/polyfill-php84 との差異調査 (#81) を踏まえ、丸め経路を
phpseclib BigInteger 依存から純粋な文字列桁演算へ刷新する。

- RoundingMode を backed string enum から純粋 enum に変更し、
  ネイティブ PHP 8.4 と完全一致させる (fix 1)
- bcround の HalfEven/HalfOdd における float フォールバックを撤廃。
  大きい数・高精度でもネイティブと一致する任意精度丸めに (closes #36)
- 方向系4モード (TowardsZero/AwayFromZero/PositiveInfinity/
  NegativeInfinity) を実装し、負 precision でもネイティブ一致
- bcfloor/bcceil を丸めコアへ委譲し高速化 (bcceil の add 依存を解消)
- bcdivmod を BCMath::div/mod ベースで実装。拡張なし環境でも動作する
  真のポリフィルとなる (closes #39)
- bc関数ラッパーの引数名を $operand から $num へ統一しネイティブ準拠。
  名前付き引数に対応 (fix 2)

丸めアルゴリズムは symfony/polyfill-php84 (MIT) の手法を参考にした
clean re-implementation で、コードの複製はしていない。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- 方向系モードが ValueError を投げる前提だった旧テストを、
  ネイティブ一致の正結果検証へ変更
- 高精度 HalfEven/HalfOdd の回帰テストを追加 (float フォールバック
  時代のバグ: 12345678901234567890.5 や 2^53 付近の欠落を検出)
- bcdivmod / 0除算のテストを追加
- phpstan: 純粋 enum 化に伴う match の default 追加と、bcmath 拡張
  ロード時にネイティブ bcround 型で解決される場合の ignore を調整

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
方向系モードと bcdivmod の実装により、以下8件の公式 phpt テストが
拡張なし環境でも通るようになったため --skip から除外する:
bcdivmod, bcdivmod_by_zero, bcround_all, bcround_away_from_zero,
bcround_ceiling, bcround_floor, bcround_toward_zero, bcround_early_return

README には bcdivmod・全RoundingMode対応と、symfony/polyfill-php84
との共存挙動 (PHP 8.2/8.3 + 拡張ありでのオートロード順) を追記。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Jul 3, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@nanasess, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 40 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 677c0096-313e-4d16-a928-efe876110a01

📥 Commits

Reviewing files that changed from the base of the PR and between 7a3eab6 and 6267255.

📒 Files selected for processing (4)
  • README.md
  • phpstan.neon.dist
  • src/BCMath.php
  • tests/BCMathTest.php
📝 Walkthrough

Walkthrough

RoundingModeのpure enum化と方向系モード(TowardsZero、AwayFromZero、NegativeInfinity)対応を追加し、BCMathの丸めコアを文字列桁演算ベースへ再実装した。あわせてbcdivmod関数/BCMath::divmodメソッドを新規追加し、関連するテスト、README、CI、phpstan設定を更新した。

Changes

RoundingMode拡張とbcdivmod追加

Layer / File(s) Summary
RoundingMode enumのpure化
lib/RoundingMode.php
enum RoundingMode: stringから backing無しのpure enumへ変更し、PHP 8.4挙動との整合性ドキュメントを更新。
丸めコアの再実装
src/BCMath.php
ROUND_*正規化トークン追加、roundToInteger/roundDigits/convertRoundingModeによる文字列桁演算ベースの丸めコアへ全面置換、floor/ceil/roundを新コアへ委譲。
bcfloor/bcceil/bcroundラッパー更新
lib/bcmath.php, phpstan.neon.dist
引数名を$operandから$numへ変更し、$modeの型ドキュメントを更新、phpstan無視エラーメッセージを対応する型表現へ更新。
bcdivmod/divmodの新規実装
src/BCMath.php, lib/bcmath.php
BCMath::divmod(div/modの合成で商・剰余を返す)とbcdivmod関数を新規追加。
丸め・divmodテスト更新
tests/BCMathTest.php
方向系RoundingModeの期待値をValueErrorから実際の丸め結果検証へ置換、環境検出にPositiveInfinity追加、高精度回帰テスト・divmod/divmodByZeroテストを新規追加。
ドキュメント・CI更新
README.md, .github/workflows/ci.yml
bcdivmodと方向系RoundingModeの対応をREADMEに追記、polyfill併存時の挙動説明を追加、CIのPHPTスキップリストからbcdivmod/bcround関連ケースを除去。

Estimated code review effort: 4 (Complex) | ~60 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Caller
  participant BCMathRound as BCMath::round
  participant ConvertMode as convertRoundingMode
  participant RoundDigits as roundDigits

  Caller->>BCMathRound: round(num, precision, mode)
  BCMathRound->>ConvertMode: convertRoundingMode(mode)
  ConvertMode-->>BCMathRound: ROUND_*トークン
  BCMathRound->>RoundDigits: roundDigits(num, precision, token)
  RoundDigits-->>BCMathRound: 丸め結果文字列
  BCMathRound-->>Caller: 丸め結果
Loading
sequenceDiagram
  participant Caller
  participant bcdivmod
  participant BCMathDivmod as BCMath::divmod
  participant Div as div
  participant Mod as mod

  Caller->>bcdivmod: bcdivmod(num1, num2, scale)
  bcdivmod->>BCMathDivmod: divmod(num1, num2, scale)
  BCMathDivmod->>Div: div(num1, num2, 0)
  BCMathDivmod->>Mod: mod(num1, num2, scale)
  BCMathDivmod-->>bcdivmod: [商, 剰余]
  bcdivmod-->>Caller: [商, 剰余]
Loading

Possibly related issues

Possibly related PRs

  • nanasess/bcmath-polyfill#57: 同じlib/RoundingMode.phpのenum/polyfill挙動を対象に変更しており、PHP 8.4丸めモードのポリフィル実装が重複する領域。

Poem

丸めの道を きれいに整え 🐇
ゼロへ、遠くへ、跳ねる数字たち
divmod抱えて 商と余り
テストの草原 駆け抜けて
にんじん片手に コミットひとつ 🥕

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Linked Issues check ✅ Passed #36 の追加 RoundingMode 対応と #39 の bcdivmod 追加が、実装・テスト・文書更新まで含めて満たされています。
Out of Scope Changes check ✅ Passed README、CI、PHPStan、テスト更新はいずれも PR の目的に沿っており、明確な範囲外変更は見当たりません。
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed 主要な変更である丸め実装の刷新、全RoundingMode対応、bcdivmod追加を的確に要約しています。
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch worktree-feat+symfony-compat-rounding

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions

github-actions Bot commented Jul 3, 2026

Copy link
Copy Markdown

🚀 Performance Benchmark Results

Configuration

  • PHP Version: 8.2
  • Iterations: 1,000 (quick mode for PR)
  • Commit: 626725516fd5adee72e80f8c39fd24435702e4c0

Performance Summary

Polyfill is 1.7x compared to native BCMath

📊 View Detailed Results

BCMath Performance Benchmark Results

Operation Context Native Time Polyfill Time Ratio
bcadd Small numbers (10 digits) 0.311ms 8.072ms 25.96x
bcsub Small numbers (10 digits) 0.283ms 8.012ms 28.31x
bcmul Small numbers (10 digits) 0.335ms 11.327ms 33.81x
bcdiv Small numbers (10 digits) 0.293ms 11.594ms 39.57x
bcadd Decimals (scale=10) 0.267ms 8.328ms 31.19x
bcsub Decimals (scale=10) 0.272ms 8.412ms 30.92x
bcmul Decimals (scale=10) 0.393ms 11.981ms 30.47x
bcdiv Decimals (scale=10) 0.698ms 12.155ms 17.42x
bcadd Medium numbers (50 digits) 0.430ms 10.207ms 23.74x
bcsub Medium numbers (50 digits) 0.374ms 10.274ms 27.46x
bcmul Medium numbers (50 digits) 1.808ms 13.871ms 7.67x
bcdiv Medium numbers (50 digits) 0.355ms 13.865ms 39.06x
bcpow Power (small exponent) 0.422ms 34.398ms 81.51x
bcpow Power (large base) 0.617ms 28.483ms 46.16x
bcsqrt Square root 5.406ms 4.418ms 0.82x
bcmod Modulo 0.624ms 11.045ms 17.70x
bcadd 100 digits 0.668ms 10.913ms 16.34x
bcmul 100 digits (first 50 digits) 2.462ms 13.588ms 5.52x
bcadd 500 digits 1.834ms 18.887ms 10.30x
bcmul 500 digits (first 50 digits) 2.457ms 13.601ms 5.54x
bcadd 1000 digits 3.380ms 30.029ms 8.88x
bcdiv Scale 20 0.842ms 12.377ms 14.70x
bcsqrt Scale 20 6.808ms 5.664ms 0.83x
bcdiv Scale 50 1.757ms 12.846ms 7.31x
bcsqrt Scale 50 22.440ms 11.066ms 0.49x
bcdiv Scale 100 3.365ms 13.101ms 3.89x
bcsqrt Scale 100 158.905ms 20.125ms 0.13x

Note: Showing partial results. Run with /benchmark comment for full results.

Quick Summary

Summary
========================================
Average performance ratio: 1.69x
Polyfill is on average 1.7x slower than native


🤖 Triggered by @nanasess with /benchmark command
💡 Comment with /benchmark to re-run this test

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request updates the PHP 8.4 bcmath polyfill by implementing the bcdivmod() function and fully supporting all eight native RoundingMode enum cases (including directional modes) using exact string-digit arithmetic. It also refactors the RoundingMode polyfill to be a pure enum, matching PHP 8.4's native behavior. The review feedback suggests a performance optimization for BCMath::divmod() to compute both the quotient and remainder in a single phpseclib BigInteger::divide() call, avoiding the overhead of performing the division twice through separate div() and mod() calls.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment thread src/BCMath.php

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🧹 Nitpick comments (1)
tests/BCMathTest.php (1)

2110-2132: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

testDivmod にネイティブbcdivmod()との比較を追加することを推奨。

testDiv/testMod/testRoundAllModesなど既存のテストはfunction_exists()でネイティブ関数が利用可能な場合にポリフィルとネイティブの結果を突き合わせていますが、testDivmodにはこのパターンがありません。CIのPHPTスキップリストからbcdivmod関連ケースが除去された(PR概要より)ことも踏まえると、PHP 8.4+環境でネイティブbcdivmod()とも一致することを検証しておくと、既存パターンとの一貫性が保て、リグレッション検出力も上がります。

♻️ 提案する追加検証
         foreach ($cases as [$num1, $num2, $scale, $expectedQuot, $expectedRem]) {
             [$quot, $rem] = BCMath::divmod($num1, $num2, $scale);
             $this->assertSame($expectedQuot, $quot, "quotient of {$num1} / {$num2} @ {$scale}");
             $this->assertSame($expectedRem, $rem, "remainder of {$num1} / {$num2} @ {$scale}");
+
+            if (function_exists('bcdivmod')) {
+                // `@phpstan-ignore-next-line`
+                $this->assertSame([$expectedQuot, $expectedRem], bcdivmod($num1, $num2, $scale));
+            }
         }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/BCMathTest.php` around lines 2110 - 2132, `testDivmod` is missing the
same native-vs-polyfill consistency check used by `testDiv`, `testMod`, and
`testRoundAllModes`. Update `BCMathTest::testDivmod` to conditionally compare
`BCMath::divmod()` against native `bcdivmod()` when
`function_exists('bcdivmod')` is true, using the same cases already in the test.
Keep the existing quotient/remainder assertions, and add a native comparison
path to verify both results match `bcdivmod()` in PHP 8.4+ environments.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@phpstan.neon.dist`:
- Line 32: The PHPStan ignore pattern in the config is treating `string|int` as
a regex alternation instead of a literal union type, so the match is too broad.
Update the message pattern in the phpstan.neon.dist entry to escape the pipe in
`(string|int) given` so it matches the literal text emitted by
`BCMath::round`/`bcround` and not regex alternatives.

In `@src/BCMath.php`:
- Around line 1158-1160: In BCMath’s rounding/shift handling, the half-rounding
path still builds a huge zero-filled string via str_repeat() when $precision is
very negative and the result should be 0. Update the relevant logic in BCMath so
that the zero-result case is detected and returned early before constructing
$scaledFrac, using the existing shifted/rounded-flow symbols around the $shift >
$intLength branch and the half-mode handling near the later rounding block.
- Around line 1045-1054: bcroundHelper() is bypassing the same validation path
used by round() because it calls roundDigits() directly. Update bcroundHelper()
so it delegates through round() or a shared validation helper, ensuring number,
precision, and mode are validated consistently before rounding. Keep the
existing bcroundHelper() and roundDigits() symbols in place, but make the public
helper follow the same checks as round() instead of returning or processing
invalid inputs directly.

---

Nitpick comments:
In `@tests/BCMathTest.php`:
- Around line 2110-2132: `testDivmod` is missing the same native-vs-polyfill
consistency check used by `testDiv`, `testMod`, and `testRoundAllModes`. Update
`BCMathTest::testDivmod` to conditionally compare `BCMath::divmod()` against
native `bcdivmod()` when `function_exists('bcdivmod')` is true, using the same
cases already in the test. Keep the existing quotient/remainder assertions, and
add a native comparison path to verify both results match `bcdivmod()` in PHP
8.4+ environments.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 22394793-5c45-4c68-b871-7c8a4e253c16

📥 Commits

Reviewing files that changed from the base of the PR and between 56f84b8 and 7a3eab6.

📒 Files selected for processing (7)
  • .github/workflows/ci.yml
  • README.md
  • lib/RoundingMode.php
  • lib/bcmath.php
  • phpstan.neon.dist
  • src/BCMath.php
  • tests/BCMathTest.php

Comment thread phpstan.neon.dist
Comment thread src/BCMath.php Outdated
Comment thread src/BCMath.php Outdated
- Key Differences 表を3者比較 (phpseclib/bcmath_compat, symfony/
  polyfill-php84, bcmath-polyfill) に拡張。拡張非依存性・bcdivmod・
  全RoundingMode対応・純粋enum・丸め方式の違いを明記
- 古くなった「RoundingMode Enum Limitations」節を削除 (全モード対応済み)
- PHP 8.1 の phpstan が in_array を常に true と誤判定する既存エラー
  (main でも failure) を ignore。bcpow を2引数目テストから除外する
  意図的ガードのため該当コードは維持

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@nanasess nanasess changed the title feat: 丸めを文字列アルゴリズム化し全RoundingMode対応・bcdivmod追加 (closes #36, #39) feat: rewrite rounding as a string-digit algorithm; support all RoundingMode modes and bcdivmod (closes #36, #39) Jul 3, 2026
- bcdivmod: 除算を1回に統合し高速化。剰余は num1 - num2×商 で明示計算し
  bcmod の切り捨て規約に一致させる(phpseclib divide() の剰余は非負規約で
  負のオペランドでずれるため)(gemini 指摘)
- bcroundHelper: round() へ委譲し、数値・precision・mode 検証を共通化
  (coderabbit 指摘: 公開helperが検証を迂回していた)
- 丸め: 巨大な負 precision でゼロ結果になる入力の str_repeat 割り当てを回避
  (dropped桁は圧縮表現、ゼロ結果は短絡)(coderabbit 指摘)
- testDivmod: ネイティブ bcdivmod との一致検証を追加(coderabbit 指摘)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@nanasess

nanasess commented Jul 3, 2026

Copy link
Copy Markdown
Owner Author

/benchmark

@nanasess
nanasess merged commit 3b6ddcd into main Jul 3, 2026
76 checks passed
@github-actions

github-actions Bot commented Jul 3, 2026

Copy link
Copy Markdown

🚀 Performance Benchmark Results

Benchmark executed on merge to main branch from PR #82

Configuration

  • Iterations per test: 10,000
  • PHP Version: 8.2
  • Extension: bcmath (native) vs polyfill

Results

📊 Detailed Benchmark Results (click to expand)

BCMath Performance Benchmark Results

Operation Context Native Time Polyfill Time Ratio
bcadd Small numbers (10 digits) 2.851ms 79.571ms 27.91x
bcsub Small numbers (10 digits) 2.456ms 77.424ms 31.53x
bcmul Small numbers (10 digits) 3.271ms 112.927ms 34.52x
bcdiv Small numbers (10 digits) 2.510ms 114.095ms 45.45x
bcadd Decimals (scale=10) 2.361ms 81.720ms 34.61x
bcsub Decimals (scale=10) 2.517ms 82.631ms 32.83x
bcmul Decimals (scale=10) 3.906ms 117.228ms 30.01x
bcdiv Decimals (scale=10) 6.959ms 118.812ms 17.07x
bcadd Medium numbers (50 digits) 3.573ms 108.748ms 30.44x
bcsub Medium numbers (50 digits) 3.748ms 100.551ms 26.83x
bcmul Medium numbers (50 digits) 18.073ms 136.528ms 7.55x
bcdiv Medium numbers (50 digits) 3.246ms 134.434ms 41.42x
bcpow Power (small exponent) 3.500ms 328.075ms 93.74x
bcpow Power (large base) 5.512ms 292.089ms 52.99x
bcsqrt Square root 53.541ms 43.201ms 0.81x
bcmod Modulo 4.880ms 108.634ms 22.26x
bcadd 100 digits 4.990ms 105.734ms 21.19x
bcmul 100 digits (first 50 digits) 24.593ms 136.354ms 5.54x
bcadd 500 digits 18.868ms 181.732ms 9.63x
bcmul 500 digits (first 50 digits) 24.353ms 135.978ms 5.58x
bcadd 1000 digits 33.752ms 298.375ms 8.84x
bcdiv Scale 20 9.338ms 120.133ms 12.87x
bcsqrt Scale 20 67.648ms 56.972ms 0.84x
bcdiv Scale 50 17.501ms 124.374ms 7.11x
bcsqrt Scale 50 222.542ms 107.895ms 0.48x
bcdiv Scale 100 33.511ms 128.974ms 3.85x
bcsqrt Scale 100 1567.409ms 200.583ms 0.13x

Summary

Summary
========================================
Average performance ratio: 1.67x
Polyfill is on average 1.7x slower than native


🤖 Generated automatically by GitHub Actions

@nanasess
nanasess deleted the worktree-feat+symfony-compat-rounding branch July 3, 2026 09:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add support for bcdivmod function Add support for additional RoundingMode enums (TowardsZero, AwayFromZero, NegativeInfinity)

1 participant